package com.example.demo.controller;

import com.example.demo.config.concurrent.ConCallable;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 这里模拟10万条数据，然后多线程处理。
 * Created by Administrator on 2018/09/27 0027.
 */
@RestController
@RequestMapping("testController")
public class TestController {

    private static final Logger log = LoggerFactory.getLogger(TestController.class);

    @RequestMapping("test1")
    public String test1() {
        try {
            //10万条数据
            List<String> list = new ArrayList<>();
            List<String> list2 = new ArrayList<>();

            for(int i = 1; i <= 100000;i++){
                list.add("test:"+i);
            }

            //每条线程处理的数据尺寸
            int size = 250;
            int count = list.size() / size;
            if (count * size != list.size()) {
                count ++;
            }

            int countNum = 0;
            final CountDownLatch countDownLatch = new CountDownLatch(count);
            ExecutorService executorService = Executors.newFixedThreadPool(8);
            ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);
            while (countNum < list.size()) {
                countNum += size;
                ConCallable callable = new ConCallable();
                //截取list的数据，分给不同线程处理
                callable.setList(ImmutableList.copyOf(list.subList(countNum - size, countNum < list.size() ? countNum :list.size())));
                ListenableFuture listenableFuture = listeningExecutorService.submit(callable);
                Futures.addCallback(listenableFuture, new FutureCallback<List<String>>() {
                    @Override
                    public void onSuccess(List<String> result) {
                        countDownLatch.countDown();
                        list2.addAll(result);
                    }

                    @Override
                    public void onFailure(Throwable t) {
                        countDownLatch.countDown();
                        log.info("处理出错：", t);
                    }
                });
            }
            countDownLatch.await(30, TimeUnit.MINUTES);
            log.info("符合条件的返回数据个数为：", list2.size());
            log.info("回调函数：", list2.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "正在处理。。。。";
    }
}
